package cn.harry.cabinet.hardware.device

import android.util.Log
import cn.harry.cabinet.hardware.SerialCommunicationListenerAdapter
import cn.harry.cabinet.hardware.SerialPortManager
import cn.harry.cabinet.utils.CardDataParser
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow

/**
 * 刷卡器设备
 * 负责卡片读取、验证等功能
 */
class CardReaderDevice(
    val deviceName: String = "刷卡器",
    private val serialPortPath: String = "/dev/ttyS4"  // 刷卡器串口路径（可配置）
) {

    companion object {
        private const val TAG = "CardReaderDevice"

    }

    // 卡片信息
    data class CardInfo(
        val cardId: String,
        val cardType: CardType,
        val readTime: Long = System.currentTimeMillis()
    )

    // 卡片类型
    enum class CardType(val value: Byte) {
        UNKNOWN(0x00),
        MIFARE_CLASSIC(0x01),
        MIFARE_ULTRALIGHT(0x02),
        ISO14443A(0x04)
    }


    // 读卡事件
    private val _cardReadEvent = MutableStateFlow<CardInfo?>(null)
    val cardReadEvent: StateFlow<CardInfo?> = _cardReadEvent.asStateFlow()

    // 串口管理器实例
    private val serialPortManager = SerialPortManager.getInstance()

    // 自动监听模式标志
    private var isAutoListeningEnabled = false

    // 通信监听器
    private val communicationListener = object : SerialCommunicationListenerAdapter() {
        override fun onDataReceived(devicePath: String, data: ByteArray, timestamp: Long) {
            Log.d(TAG, "通信监听器收到数据 - 串口: $devicePath, 数据长度: ${data.size}")
            Log.d(TAG, "当前刷卡器配置串口: $serialPortPath")
            
            // 只处理刷卡器配置的串口数据，忽略其他串口的数据
            if (devicePath == serialPortPath) {
                Log.i(TAG, "串口匹配成功，开始处理数据")
                handleReceivedData(data)
            } else {
                Log.w(TAG, "串口不匹配，忽略数据 - 期望: $serialPortPath, 实际: $devicePath")
            }
        }
    }

    init {
        // 注册通信监听器
        serialPortManager.addCommunicationListener(communicationListener)
        Log.i(TAG, "CardReaderDevice 初始化完成 - 串口: $serialPortPath")
        Log.d(TAG, "通信监听器已注册到 SerialPortManager")
    }

    /**
     * 映射解析类型到卡片类型
     */
    private fun mapParseTypeToCardType(parseType: String): CardType {
        return when (parseType.uppercase()) {
            "ASCII_HEX", "ASCII" -> CardType.MIFARE_CLASSIC
            "HEX" -> CardType.ISO14443A
            "WIEGAND" -> CardType.MIFARE_ULTRALIGHT
            else -> CardType.UNKNOWN
        }
    }

    /**
     * 启动自动监听模式 - 持续监听刷卡数据
     */
    fun startAutoListening() {
        Log.d(TAG, "启动刷卡器自动监听模式")
        Log.d(TAG, "刷卡器串口路径: $serialPortPath")
        Log.d(TAG, "串口管理器连接状态: ${serialPortManager.isConnected()}")

        if (!serialPortManager.isConnected()) {
            Log.w(TAG, "串口未连接，无法启动自动监听")
            return
        }

        // 启用自动监听标志，数据将由通信监听器自动处理
        isAutoListeningEnabled = true

        Log.i(TAG, "刷卡器自动监听模式已启动 - 监听串口: $serialPortPath")
        Log.i(TAG, "通信监听器已注册，等待数据...")
    }

    /**
     * 停止自动监听模式
     */
    fun stopAutoListening() {
        Log.d(TAG, "停止刷卡器自动监听模式")
        isAutoListeningEnabled = false
        Log.i(TAG, "刷卡器自动监听模式已停止")
    }

    /**
     * 清除读卡事件
     */
    fun clearCardReadEvent() {
        _cardReadEvent.value = null
    }


    /**
     * 处理接收到的数据
     * 只在自动监听模式下处理
     */
    private fun handleReceivedData(data: ByteArray) {
        Log.d(TAG, "handleReceivedData 被调用 - 数据长度: ${data.size}, 自动监听状态: $isAutoListeningEnabled")
        
        // 如果启用了自动监听模式，尝试解析卡片数据
        if (isAutoListeningEnabled) {
            try {
                Log.i(TAG, "自动监听接收到数据: ${data.size} 字节")
                Log.d(TAG, "原始数据(HEX): ${data.joinToString(" ") { "%02X".format(it) }}")

                // 使用CardDataParser解析数据
                val parseResult = CardDataParser.parseCardData(data, data.size)

                if (parseResult.success && CardDataParser.isValidCardId(parseResult.cardId)) {
                    // 创建CardInfo
                    val cardInfo = CardInfo(
                        cardId = parseResult.cardId,
                        cardType = mapParseTypeToCardType(parseResult.cardType)
                    )

                    Log.i(
                        TAG,
                        "自动监听读卡成功: ${cardInfo.cardId}, 解析方法: ${parseResult.parseMethod}"
                    )

                    // 触发读卡事件
                    _cardReadEvent.value = cardInfo

                    // 刷卡器是被动设备，不支持LED和蜂鸣器控制命令，移除这些调用
                }
            } catch (e: Exception) {
                Log.e(TAG, "自动监听数据处理异常: ${e.message}", e)
            }
        } else {
            // 非自动监听模式，只记录接收到的数据（用于readCard方法）
            Log.d(TAG, "接收到数据: ${data.size} 字节")
        }
    }
}